package com.example.springboot.service.admin.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springboot.config.Shiro.security.SecurityUtil;
import com.example.springboot.mapper.*;
import com.example.springboot.model.entity.*;
import com.example.springboot.model.form.PageUtil;
import com.example.springboot.model.form.Result;
import com.example.springboot.model.req.admin.EnshrineReq;
import com.example.springboot.model.req.admin.LikeReq;
import com.example.springboot.model.req.admin.MaterialReq;
import com.example.springboot.model.sys.SysUser;
import com.example.springboot.model.vo.CommentVO;
import com.example.springboot.model.vo.MaterialVO;
import com.example.springboot.model.vo.TagVO;
import com.example.springboot.service.admin.MaterialService;
import com.example.springboot.utils.CopyUtil;
import com.example.springboot.utils.StringUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author zf
 * @素材表
 * @since 2021-03-17
 */
@Service
public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> implements MaterialService {

    @Resource
    CommentMapper commentMapper;

    @Resource
    MetasMapper metasMapper;

    @Resource
    TagMapper tagMapper;

    @Resource
    DataTagMapper dataTagMapper;

    @Resource
    EnshrineMapper enshrineMapper;

    @Resource
    LikeMapper likeMapper;

    @Resource
    CmsUserMapper cmsUserMapper;

    @Override
    public Result getPage(MaterialReq req) {
        SysUser sysUser = SecurityUtil.sysUser();

        List<Integer> ids = null;

        if (Objects.nonNull(req.getDynamicTags()) && req.getDynamicTags().length > 0){
            Tag tag = tagMapper.selectOne(new LambdaQueryWrapper<Tag>()
                    .eq(Tag::getInvalid, 0)
                    .eq(Tag::getName, req.getDynamicTags()[0]));
            List<DataTag> dataTags = dataTagMapper.selectList(new LambdaQueryWrapper<DataTag>()
                    .eq(DataTag::getInvalid, 0)
                    .eq(DataTag::getTagId, tag.getId()));
            ids = dataTags.stream().map(e -> e.getDataId()).collect(Collectors.toList());
            ids.add(-1);
        }

        if (Objects.nonNull(sysUser) && Objects.nonNull(req.getIsEnshrine())) {
            List<Enshrine> enshrineList = enshrineMapper.selectList(new LambdaQueryWrapper<Enshrine>()
                    .eq(Enshrine::getInvalid, 0)
                    .eq(Enshrine::getUserId, sysUser.getId()));
            ids = enshrineList.stream().map(e -> e.getEnshrineId()).collect(Collectors.toList());
            ids.add(-1);
        }
        LambdaQueryWrapper<Material> materialLambdaQueryWrapper = new LambdaQueryWrapper<Material>()
                .eq(Material::getInvalid, 0)
                .in(Objects.nonNull(ids),Material::getId,ids)
                .eq(Objects.nonNull(req.getMetasId()),Material::getMetasId,req.getMetasId())
                .like(StringUtil.isNotBlank(req.getSource()), Material::getSource, req.getSource())
                .like(StringUtil.isNotBlank(req.getContent()), Material::getContent, req.getContent())
                .like(StringUtil.isNotBlank(req.getAuthor()), Material::getAuthor, req.getAuthor())
                .orderByDesc(Material::getHits)
                .orderByDesc(Material::getCreateTime);
        if (Objects.nonNull(sysUser)) {
            materialLambdaQueryWrapper.eq(Objects.nonNull(req.getIsMy()) && req.getIsMy() == 1, Material::getUserId, sysUser.getId());
        }
        IPage<Material> ipage = page(req.toPage(), materialLambdaQueryWrapper);

        if (ipage.getRecords().size()<1){
            return Result.buildFail("已经到底了呦。。。");
        }
        Page<Material> page = PageUtil.toPage(ipage);
        return Result.buildSuccess(PageUtil.convert(page, e -> {
            MaterialVO vo = CopyUtil.copyObject(e, MaterialVO.class);
            //评论数据
            List<Comment> comments = commentMapper.selectList(new LambdaQueryWrapper<Comment>()
                    .eq(Comment::getInvalid, 0)
                    .eq(Comment::getCid, e.getId())
                    .eq(Comment::getType, 0));
            vo.setCommentVOList(CopyUtil.copyList(comments, CommentVO.class));

            //分类
            Metas meta = metasMapper.selectById(e.getMetasId());
            if (Objects.nonNull(meta)) {
                vo.setMetasName(meta.getName());
            }
            if (Objects.nonNull(sysUser)) {
                //收藏
                Enshrine enshrine = enshrineMapper.selectOne(new LambdaQueryWrapper<Enshrine>()
                        .eq(Enshrine::getInvalid, 0)
                        .eq(Enshrine::getUserId, sysUser.getId())
                        .eq(Enshrine::getEnshrineId, e.getId()));
                if (Objects.nonNull(enshrine)) {
                    vo.setIsEnshrine(1);
                }
                //点赞
                Like like = likeMapper.selectOne(new LambdaQueryWrapper<Like>()
                        .eq(Like::getInvalid, 0)
                        .eq(Like::getUserId, sysUser.getId())
                        .eq(Like::getLikeId, e.getId()));
                if (Objects.nonNull(like)) {
                    vo.setIsLike(1);
                }
            }
            return vo;
        }));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result addInfo(MaterialReq req) {
        if (StringUtil.isBlank(req.getContent())) {
            return Result.buildFail("参数错误！");
        }
        SysUser sysUser = SecurityUtil.sysUser();
        req.setContent(req.getContent().replaceAll("\n", "<br>"));
        Material one = getOne(new LambdaQueryWrapper<Material>()
                .eq(Material::getInvalid, 0)
                .eq(Material::getUserId, sysUser.getId())
                .eq(Material::getContent, req.getContent())
                .ne(Objects.nonNull(req.getId()),Material::getId,req.getId()));
        if (Objects.nonNull(one)) {
            return Result.buildFail("您已发过此句子！");
        }
        Material material = CopyUtil.copyObject(req, Material.class);
        material.setUserId(sysUser.getId());

        boolean flag;
        if (Objects.nonNull(req.getId())) {
            DataTag dataTag = new DataTag();
            dataTag.setInvalid(1);
            dataTagMapper.update(dataTag, new LambdaUpdateWrapper<DataTag>()
                    .eq(DataTag::getUserId, sysUser.getId())
                    .eq(DataTag::getDataId, req.getId()));
            flag = updateById(material);
        } else {
            flag = save(material);
        }
        if (flag) {
            //标签
            if(Objects.nonNull(req.getDynamicTags()) && req.getDynamicTags().length > 0){
                for (String dynamicTag : req.getDynamicTags()) {
                    Tag tag = tagMapper.selectOne(new LambdaUpdateWrapper<Tag>()
                            .eq(Tag::getName, dynamicTag));
                    if (Objects.isNull(tag)) {
                        tag = new Tag();
                        tag.setName(dynamicTag);
                        tagMapper.insert(tag);
                    }
                    DataTag dataTag = new DataTag();
                    dataTag.setUserId(sysUser.getId());
                    dataTag.setDataId(material.getId());
                    dataTag.setTagId(tag.getId());
                    dataTagMapper.insert(dataTag);
                }
            }
            return Result.buildSuccess();
        }
        return Result.buildFail();
    }

    @Override
    public Result getInfo(Integer id) {
        Material byId = getById(id);
        //主表复制元素
        MaterialVO vo = CopyUtil.copyObject(byId, MaterialVO.class);
        //评论数据
        List<Comment> comments = commentMapper.selectList(new LambdaQueryWrapper<Comment>()
                .eq(Comment::getInvalid, 0)
                .eq(Comment::getType, 0)
                .eq(Comment::getCid, byId.getId()));
        List<CommentVO> commentVOS = CopyUtil.copyList(comments, CommentVO.class);
        for (CommentVO commentVO : commentVOS) {
            CmsUser cmsUser = cmsUserMapper.selectById(commentVO.getAuthorId());
            commentVO.setAuthor(cmsUser.getRealname());
            commentVO.setAuthorHeadImg(cmsUser.getHeadImg());
        }
        vo.setCommentVOList(commentVOS);

        CmsUser user = cmsUserMapper.selectById(byId.getUserId());
        vo.setHeadImg(user.getHeadImg());
        vo.setRealname(user.getRealname());

        //分类
        Metas meta = metasMapper.selectById(byId.getMetasId());
        if (Objects.nonNull(meta)) {
            vo.setMetasName(meta.getName());
        }
        List<DataTag> dataTags = dataTagMapper.selectList(new LambdaQueryWrapper<DataTag>()
                .eq(DataTag::getDataId, id)
                .eq(DataTag::getInvalid, 0));
        List<Integer> list = dataTags.stream().map(e -> e.getTagId()).collect(Collectors.toList());
        list.add(-1);
        List<Tag> tags = tagMapper.selectList(new LambdaQueryWrapper<Tag>()
                .eq(Tag::getInvalid, 0)
                .in(Tag::getId, list));
        vo.setTagList(CopyUtil.copyList(tags, TagVO.class));

        //热点增加
        update(new UpdateWrapper<Material>().lambda()
                .set(Material::getHits, byId.getHits() + 1)
                .eq(Material::getId, id));
        return Result.buildSuccess(vo);
    }

    @Override
    public Result deleteInfos(String ids) {
        if (update(new UpdateWrapper<Material>().lambda()
                .set(Material::getInvalid, 1)
                .inSql(Material::getId, ids)
        )) {
            return Result.buildSuccess();
        }
        return Result.buildFail();
    }

    @Override
    public Result enshrineSave(EnshrineReq req) {
        SysUser sysUser = SecurityUtil.sysUser();
        Enshrine enshrine = CopyUtil.copyObject(req, Enshrine.class);
        enshrine.setUserId(sysUser.getId());
        enshrineMapper.insert(enshrine);
        return Result.buildSuccess();
    }

    @Override
    public Result enshrineCancel(EnshrineReq req) {
        SysUser sysUser = SecurityUtil.sysUser();
        Enshrine enshrine = new Enshrine();
        enshrine.setInvalid(1);
        enshrineMapper.update(enshrine, new LambdaQueryWrapper<Enshrine>()
                .eq(Enshrine::getUserId, sysUser.getId())
                .eq(Enshrine::getEnshrineId, req.getId()));
        return Result.buildSuccess();
    }

    @Override
    public Result likeSave(LikeReq req) {
        SysUser sysUser = SecurityUtil.sysUser();
        Like like = CopyUtil.copyObject(req, Like.class);
        like.setUserId(sysUser.getId());
        likeMapper.insert(like);
        return Result.buildSuccess();
    }

    @Override
    public Result likeCancel(LikeReq req) {
        SysUser sysUser = SecurityUtil.sysUser();
        Like like = new Like();
        like.setInvalid(1);
        likeMapper.update(like, new LambdaQueryWrapper<Like>()
                .eq(Like::getUserId, sysUser.getId())
                .eq(Like::getLikeId, req.getId()));
        return Result.buildSuccess();
    }

}